#if  (FEATURE_MODE == 0)
/**
 @file ctc_pon_cli.c

 @author  Copyright (C) 2021 Centec Networks Inc.  All rights reserved.

 @date 2021-06-30

 @version v1.0

 This file define pon sample CLI functions

*/

#include "sal.h"
#include "ctc_api.h"
#include "ctc_cli.h"
#include "ctcs_api.h"
#include "ctc_error.h"
#include "ctc_debug.h"
#include "ctc_opf.h"
#include "ctc_chip.h"
#include "ctc_cli_common.h"
#include "ctc_pon_cli.h"
#include "ctc_app_cli.h"
#include "ctc_app_pon.h"
#include "./usw/ctc_usw_scl_cli.h"
#include "ctc_xdata.h"
#include "ctc_xdata_cli.h"

#define CTC_CLI_PON_FLEX_KEY_FIELD_TYPE_SET(p_field, arg) \
do{\
    uint8 action_begin = CTC_CLI_GET_ARGC_INDEX("action-field");\
    index = CTC_CLI_GET_ARGC_INDEX("mac-sa");\
    if (index < action_begin) \
    {\
        p_field->type =    CTC_FIELD_KEY_MAC_SA;\
        CTC_CLI_GET_MAC_ADDRESS("value", mac_sa, argv[index + 1]);\
        CTC_CLI_GET_MAC_ADDRESS("mask", macsa_mask, argv[index + 2]);\
        p_field->ext_data = (void*)mac_sa;\
        p_field->ext_mask = (void*)macsa_mask;\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("mac-da");\
    if (index < action_begin) \
    {\
        p_field->type =    CTC_FIELD_KEY_MAC_DA;\
        CTC_CLI_GET_MAC_ADDRESS("value", mac_da, argv[index + 1]);\
        CTC_CLI_GET_MAC_ADDRESS("mask", macda_mask, argv[index + 2]);\
        p_field->ext_data = (void*)mac_da;\
        p_field->ext_mask = (void*)macda_mask;\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("ip-sa");\
    if (index < action_begin) \
    {\
        p_field->type =    CTC_FIELD_KEY_IP_SA;\
        CTC_CLI_GET_IPV4_ADDRESS("value", p_field->data, argv[index + 1]);\
        CTC_CLI_GET_IPV4_ADDRESS("mask", p_field->mask, argv[index + 2]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("ip-da");\
    if (index < action_begin) \
    {\
        p_field->type =    CTC_FIELD_KEY_IP_DA;\
        CTC_CLI_GET_IPV4_ADDRESS("value", p_field->data, argv[index + 1]);\
        CTC_CLI_GET_IPV4_ADDRESS("mask", p_field->mask, argv[index + 2]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("ipv6-sa");\
    if (index < action_begin) \
    {\
        p_field->type =    CTC_FIELD_KEY_IPV6_SA;\
        CTC_CLI_GET_IPV6_ADDRESS("value", ipv6_sa, argv[index + 1]);\
        ipv6_sa[0] = sal_htonl(ipv6_sa[0]);\
        ipv6_sa[1] = sal_htonl(ipv6_sa[1]);\
        ipv6_sa[2] = sal_htonl(ipv6_sa[2]);\
        ipv6_sa[3] = sal_htonl(ipv6_sa[3]);\
        p_field->ext_data = ipv6_sa;\
        CTC_CLI_GET_IPV6_ADDRESS("mask", ipv6_sa_mask, argv[index + 2]);\
        ipv6_sa_mask[0] = sal_htonl(ipv6_sa_mask[0]);\
        ipv6_sa_mask[1] = sal_htonl(ipv6_sa_mask[1]);\
        ipv6_sa_mask[2] = sal_htonl(ipv6_sa_mask[2]);\
        ipv6_sa_mask[3] = sal_htonl(ipv6_sa_mask[3]);\
        p_field->ext_mask = ipv6_sa_mask;\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("ipv6-da");\
    if (index < action_begin) \
    {\
        p_field->type =    CTC_FIELD_KEY_IPV6_DA;\
        CTC_CLI_GET_IPV6_ADDRESS("value", ipv6_da, argv[index + 1]);\
        ipv6_da[0] = sal_htonl(ipv6_da[0]);\
        ipv6_da[1] = sal_htonl(ipv6_da[1]);\
        ipv6_da[2] = sal_htonl(ipv6_da[2]);\
        ipv6_da[3] = sal_htonl(ipv6_da[3]);\
        p_field->ext_data = ipv6_da;\
        CTC_CLI_GET_IPV6_ADDRESS("mask", ipv6_da_mask, argv[index + 2]);\
        ipv6_da_mask[0] = sal_htonl(ipv6_da_mask[0]);\
        ipv6_da_mask[1] = sal_htonl(ipv6_da_mask[1]);\
        ipv6_da_mask[2] = sal_htonl(ipv6_da_mask[2]);\
        ipv6_da_mask[3] = sal_htonl(ipv6_da_mask[3]);\
        p_field->ext_mask = ipv6_da_mask;\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("l4-dst-port");\
    if (index < action_begin) \
    {\
        p_field->type =    CTC_FIELD_KEY_L4_DST_PORT;\
        CTC_CLI_GET_UINT32("value", p_field->data, argv[index + 1]);\
        CTC_CLI_GET_UINT32("mask", p_field->mask, argv[index + 2]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("l4-src-port");\
    if (index < action_begin) \
    {\
        p_field->type =    CTC_FIELD_KEY_L4_SRC_PORT;\
        CTC_CLI_GET_UINT32("value", p_field->data, argv[index + 1]);\
        CTC_CLI_GET_UINT32("mask", p_field->mask, argv[index + 2]);\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("svlan-range");\
    if (index < action_begin) \
    {\
        p_field->type =    CTC_FIELD_KEY_SVLAN_RANGE;\
        CTC_CLI_GET_UINT32("min", p_field->data, argv[index + 1])\
        CTC_CLI_GET_UINT32("max", p_field->mask, argv[index + 2])\
        index = CTC_CLI_GET_ARGC_INDEX("vrange-gid");\
        {\
            CTC_CLI_GET_UINT32("vrange-gid", vlan_mapping_group, argv[index + 1]);\
            p_field->ext_data = &vlan_mapping_group;\
        }\
        arg;\
    }\
    index = CTC_CLI_GET_ARGC_INDEX("cvlan-range");\
    if (index < action_begin) \
    {\
        p_field->type =    CTC_FIELD_KEY_CVLAN_RANGE;\
        CTC_CLI_GET_UINT32("min", p_field->data, argv[index + 1])\
        CTC_CLI_GET_UINT32("max", p_field->mask, argv[index + 2])\
        index = CTC_CLI_GET_ARGC_INDEX("vrange-gid");\
        {\
            CTC_CLI_GET_UINT32("vrange-gid", vlan_mapping_group, argv[index + 1]);\
            p_field->ext_data = &vlan_mapping_group;\
        }\
        arg;\
    }\
}while(0);


CTC_CLI(ctc_cli_pon_module_init,
        ctc_cli_pon_module_init_cmd,
        "pon module init {mode MODE|}",
        "Pon",
        "Module",
        "Init",
        "Mode",
        "MODE, if mode = 1, means ipv4/ipv6/pppoe packet use different pon service")
{
    int32 ret = 0;
    uint8 index = 0;
    ctc_pon_global_cfg_t cfg;

    sal_memset(&cfg, 0, sizeof(cfg));
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("mode");
    if (index != 0xFF)
    {
       CTC_CLI_GET_UINT8("mode", cfg.mode, argv[index+1]);
    }
    if(g_ctcs_api_en)
    {
        ret = ctcs_pon_init(g_api_ldev,&cfg);
    }
    else
    {
        ret = ctc_pon_init(&cfg);
    }
    if (ret < 0)
    {
        ctc_cli_out("%% %s\n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_pon_module_deinit,
        ctc_cli_pon_module_deinit_cmd,
        "pon module deinit ",
        "Pon",
        "Module",
        "Deinit")
{
    int32 ret = 0;
    ctc_pon_global_cfg_t cfg;

    sal_memset(&cfg, 0, sizeof(cfg));
    if(g_ctcs_api_en)
    {
        ret = ctcs_pon_deinit(g_api_ldev,&cfg);
    }
    else
    {
        ret = ctc_pon_deinit(&cfg);
    }
    if (ret < 0)
    {
        ctc_cli_out("%% %s\n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return CLI_SUCCESS;
}


CTC_CLI(ctc_cli_pon_set_properity,
        ctc_cli_pon_set_port_properity_cmd,
        "pon port GPORT (nni-port  |uni-port |logic-port)  value VALUE",
        "Pon",
        "Port",
        CTC_CLI_GPHYPORT_ID_DESC,
        "Nni-port",
        "Uni-port",
        "Logic-port",
        "Value",
        "VALUE")
{
    int32 ret = 0;
    uint32 gport = 0;
    uint8 index = 0;
    ctc_pon_port_cfg_t cfg;

    sal_memset(&cfg, 0, sizeof(cfg));
    CTC_CLI_GET_UINT32_RANGE("port", gport, argv[0], 0, CTC_MAX_UINT32_VALUE);
    CTC_CLI_GET_UINT32_RANGE("value", cfg.value, argv[2], 0, CTC_MAX_UINT32_VALUE);

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("nni-port");
    if (index != 0xFF)
    {
          cfg.type = CTC_PON_PORT_CFG_NNI_EN;
    }
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("uni-port");
    if (index != 0xFF)
    {
        cfg.type = CTC_PON_PORT_CFG_UNI_EN;
        cfg.criteria = CTC_PON_VLAN_PORT_MATCH_SVLAN_CVLAN;
    } 
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("logic-port");
    if (index != 0xFF)
    {
        cfg.type =CTC_PON_PORT_CFG_NNI_LOGIC_PORT;
    }
    if(g_ctcs_api_en)
    {
        ret = ctcs_pon_set_port_propery(g_api_ldev,gport,&cfg);
    }
    else
    {
        ret = ctc_pon_set_port_propery(gport,&cfg);
    } 
    if (ret < 0)
    {
        ctc_cli_out("%% %s\n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_pon_get_properity,
        ctc_cli_pon_get_port_properity_cmd,
        "show pon port GPORT (nni-port  |uni-port |logic-port) ",
        "Show",
        "Pon",
        "Port",
        CTC_CLI_GPHYPORT_ID_DESC,
        "Nni-port",
        "Uni-port",
        "Logic-port")
{
    int32 ret = 0;
    uint32 gport = 0;
    uint8 index = 0;
    ctc_pon_port_cfg_t cfg;

    sal_memset(&cfg, 0, sizeof(cfg));
    CTC_CLI_GET_UINT32_RANGE("port", gport, argv[0], 0, CTC_MAX_UINT32_VALUE);
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("nni-port");
    if (index != 0xFF)
    {
          cfg.type= CTC_PON_PORT_CFG_NNI_EN;
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("uni-port");
    if (index != 0xFF)
    {
        cfg.type = CTC_PON_PORT_CFG_UNI_EN;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("logic-port");
    if (index != 0xFF)
    {
        cfg.type = CTC_PON_PORT_CFG_NNI_LOGIC_PORT;
    }

    if(g_ctcs_api_en)
    {
        ret = ctcs_pon_get_port_propery(g_api_ldev,gport,&cfg);
    }
    else
    {
        ret = ctc_pon_get_port_propery(gport,&cfg);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% %s\n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
   else
    {
        ctc_cli_out("---------------------------------------------------------------\n");
        ctc_cli_out("%-10s%-10d\n","gport:" , gport);
        ctc_cli_out("%-10s%-10d\n","type:" , cfg.type);
        ctc_cli_out("%-10s%-10d\n","value:" , cfg.value);
        ctc_cli_out("%-10s%-10d\n","criteria:" , cfg.criteria);
        ctc_cli_out("---------------------------------------------------------------\n");
    }   
    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_pon_create_gem_port,
        ctc_cli_pon_create_gem_port_cmd,
        "pon (create|destroy|update) gem-port port  GPORT tunnel-vlan TUNNEL_VLAN  logic-port LOGIC_PORT (pass-through-en VALUE|limit-action (none|fwd|discard|redirect-to-cpu)| flooding|igs-policer-id IGS_POLICERID|egs-service-id EGS_SERVICEID|) ",
        "Pon",
        "Create",
        "Destroy",
        "Update",
        "Gem-port",
        "Port",
        CTC_CLI_GPHYPORT_ID_DESC,
        "Tunnel-vlan",
        "TUNNEL_VLAN",
        "Logic-port",
        "Logic_port Value",
        "Pass-through-en",
        "Pass-through-en , 1:enable,0:disable",
        "Limit-action",
        "Do nothing",
        "Forwarding packet",
        "Discard packet",
        "Redirect to cpu",
        "Flooding",
        "Ingress Policer id",
        CTC_CLI_QOS_FLOW_PLC_VAL,
        "Egress Service id",
        CTC_CLI_QOS_SERVICE_VAL)

{
    int32 ret = 0;
    uint8 index = 0;
    uint8 is_create = 0;
    uint8 is_destroy = 0;
    ctc_pon_gem_port_t cfg;
    
    sal_memset(&cfg, 0, sizeof(cfg));
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("create");
    if (index != 0xFF)
    {
        is_create = 1;
    }
    
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("destroy");
    if (index != 0xFF)
    {
        is_destroy = 1;
    }

    CTC_CLI_GET_UINT32_RANGE("gport", cfg.gport, argv[1], 0, CTC_MAX_UINT32_VALUE);
    CTC_CLI_GET_UINT32_RANGE("tunnel-vlan", cfg.tunnel_value, argv[2], 0, CTC_MAX_UINT32_VALUE);
    CTC_CLI_GET_UINT32_RANGE("logic-port", cfg.logic_port, argv[3], 0, CTC_MAX_UINT32_VALUE);

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("pass-through-en");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT8("pass-through-en", cfg.pass_through_en, argv[index++]); 
        CTC_SET_FLAG(cfg.flag,CTC_PON_GEM_PORT_FLAG_PASS_THROUGH_EN);
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("limit-action");
    if (index != 0xFF)
    {
        index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("none");
        if (index != 0xFF)
        {
            cfg.limit_action = CTC_MACLIMIT_ACTION_NONE;
        }
        index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("fwd");
        if (index != 0xFF)
        {
            cfg.limit_action = CTC_MACLIMIT_ACTION_FWD;
        }
        index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("redirect-to-cpu");
        if (index != 0xFF)
        {
            cfg.limit_action = CTC_MACLIMIT_ACTION_TOCPU;
        }
        index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("discard");
        if (index != 0xFF)
        {
            cfg.limit_action = CTC_MACLIMIT_ACTION_DISCARD;
        }
        
        CTC_SET_FLAG(cfg.flag,CTC_PON_GEM_PORT_FLAG_MAC_LIMIT);
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("flooding");
    if (index != 0xFF)
    {
        CTC_SET_FLAG(cfg.flag,CTC_PON_GEM_PORT_FLAG_FLOODING);
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("igs-policer-id");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT16("igs-policer-id", cfg.igs_policer_id, argv[index++]); 
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("egs-service-id");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT16("egs-ervice-id", cfg.egs_service_id, argv[index++]); 
    }

    if(g_ctcs_api_en)
    {
            if (is_create)
            {
                ret = ctcs_pon_create_gem_port(g_api_ldev,&cfg);
            }
            else if(is_destroy)
            {
                ret = ctcs_pon_destroy_gem_port(g_api_ldev,&cfg);
            }
            else
             {
                ret = ctcs_pon_update_gem_port(g_api_ldev,&cfg);
             }
    }
    else
    {
            if (is_create)
            {
                ret = ctc_pon_create_gem_port(&cfg);
            }
            else if(is_destroy)
            {
                ret = ctc_pon_destroy_gem_port(&cfg);
            }
            else
            {
                ret = ctc_pon_update_gem_port(&cfg);
            }
    }
    if (ret < 0)
    {
        ctc_cli_out("%% %s\n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
    return CLI_SUCCESS;
}

#define _____VLAN_PORT_____ ""

#define CTC_CLI_PON_VLAN_ACTION_OP "(none|add|del|replace)"\

#define CTC_CLI_PON_VLAN_ACTION " (svlan " CTC_CLI_PON_VLAN_ACTION_OP " (new-svid SVID|) |) " \
                                " (scos  " CTC_CLI_PON_VLAN_ACTION_OP " (new-scos SCOS|) |) " \
                                " (cvlan " CTC_CLI_PON_VLAN_ACTION_OP " (new-cvid CVID|) |) " \
                                " (ccos  " CTC_CLI_PON_VLAN_ACTION_OP " (new-ccos CCOS|) |) "

#define CTC_CLI_PON_VLAN_ACTION_OP_DSCP \
    "None",       \
    "Add",        \
    "Del",        \
    "Replace"     \

  
#define CTC_CLI_PON_VLAN_ACTION_DSCP \
    "Svlan",                              \
    CTC_CLI_PON_VLAN_ACTION_OP_DSCP,      \
    "New svid",                            \
    "Svlan value",                        \
    "Scos",                               \
    CTC_CLI_PON_VLAN_ACTION_OP_DSCP,      \
    "New scos",                            \
    "Scos value",                         \
    "Cvlan",                              \
    CTC_CLI_PON_VLAN_ACTION_OP_DSCP,      \
    "New cvid",                            \
    "Cvlan value",                        \
    "Ccos",                               \
    CTC_CLI_PON_VLAN_ACTION_OP_DSCP,      \
    "New cos",                            \
    "Cos value"                           \

STATIC int32
_ctc_app_cli_parser_vlan_action2(ctc_vti_t* vty, unsigned char argc,
                                    char** argv,
                                    uint8 start,
                                    char *field,
                                    uint8* p_vlan_action,
                                    uint8* p_vlan_sl,
                                    uint16* p_new_value)
{
    uint8 index = 0;
    uint8 start_index = 0;
    uint16 value = 0;

    start_index = CTC_CLI_GET_SPECIFIC_INDEX(field, start);
    if (start_index == 0xFF)
    {
        return 0;
    }

    index = start + start_index + 1;

    if (CLI_CLI_STR_EQUAL("none", index))
    {
        *p_vlan_action = CTC_VLAN_TAG_OP_VALID;
    }
    else if(CLI_CLI_STR_EQUAL("add", index))
    {
        *p_vlan_action = CTC_VLAN_TAG_OP_ADD;
        *p_vlan_sl = CTC_VLAN_TAG_SL_NEW;
    }
    else if(CLI_CLI_STR_EQUAL("del", index))
    {
        *p_vlan_action = CTC_VLAN_TAG_OP_DEL;
    }
    else if(CLI_CLI_STR_EQUAL("replace", index))
    {
        *p_vlan_action = CTC_VLAN_TAG_OP_REP;
        *p_vlan_sl = CTC_VLAN_TAG_SL_NEW;
    }

    index = start + start_index + 2;

    if (argv[(index)] && index < argc)
    {
        if (CLI_CLI_STR_EQUAL("new-svid", index))
        {
            CTC_CLI_GET_UINT16("new svid", value, argv[index + 1]);
        }
        else if(CLI_CLI_STR_EQUAL("new-scos", index))
        {
            CTC_CLI_GET_UINT16("new scos", value, argv[index + 1]);
        }
        else if(CLI_CLI_STR_EQUAL("new-cvid", index))
        {
            CTC_CLI_GET_UINT16("new cvid", value, argv[index + 1]);
        }
        else if(CLI_CLI_STR_EQUAL("new-ccos", index))
        {
            CTC_CLI_GET_UINT16("new ccos", value, argv[index + 1]);
        }
        *p_new_value = value;
    }
    return 0;
}

CTC_CLI(ctc_cli_pon_create_vlan_port,
        ctc_cli_pon_create_vlan_port_cmd,
        "pon  (create|destroy|update) vlan-port  (uni |nni ) (vlan-port-id VALUE port GPORT)  ( is-default | scl-id SCL_ID |) {match-tunnel-value TUNNEL | match-svlan SVLAN | match-svlan-end SVLAN  | match-cvlan CVLAN | match-cvlan-end CVLAN  |\
        match-scos SCOS | match-ccos CCOS |  \
        flex (use-mac-key | use-ipv6-key |) {mac-sa MAC MASK | mac-da MAC MASK | ip-sa A.B.C.D A.B.C.D | ip-da A.B.C.D A.B.C.D | cvlan-id CVLAN_ID MASK | ctag-cos CTAG_COS MASK |\
        svlan-id SVLAN_ID MASK | stag-cos STAG_COS MASK | l3-type L3_TYPE MASK | ctag-cfi CTAG_CFI | stag-cfi STAG_CFI | stag-valid STAG_VALID |\
        ctag-valid CTAG_VALID | vlan-num VLAN_MUM MASK | l4-src-port L4_SRC_PORT MASK | l4-dst-port L4_DST_PORT MASK | ipv6-sa X:X::X:X MASK | ipv6-da X:X::X:X MASK |} |} \
        {fid FID | volt-tag VOLT-TAG | vn-tag VNTAG |xlate-nhid NHID | dsnh-offset OFFSET | logic-port LOGIC_PORT|igs-policer-id Ingress-policer-id|igs-vlan-action" CTC_CLI_PON_VLAN_ACTION "|egs-vlan-action" CTC_CLI_PON_VLAN_ACTION "|pass-through-en |}",
        "Pon",
        "Create",
        "Destroy",
        "Update",
        "Vlan-port",
        "Uni",
        "Nni",
        "Vlan-port-id",
        "VALUE",
        "Port",
        CTC_CLI_GPHYPORT_ID_DESC,
        "Is-default",
        "scl lookup id",
        "SCL ID VALUE",
        "Match-tunnel-value",
        "Tunnel_vlan",
        "Match-svlan",
        CTC_CLI_VLAN_DESC,
        "Match-svlan-end",
        CTC_CLI_VLAN_DESC,
        "Match-cvlan",
        CTC_CLI_VLAN_DESC,
        "Match-cvlan-end",
        CTC_CLI_VLAN_DESC,
        "Match-scos",
        CTC_CLI_COS_RANGE_DESC,
        "Match-ccos",
        CTC_CLI_COS_RANGE_DESC,
        "Flexible vlan edit",
        "Use Mac key", 
        "Use Ipv6 key",
        "Mac-sa",
        CTC_CLI_MAC_FORMAT,
        CTC_CLI_MAC_FORMAT,
        "Mac-da",
        CTC_CLI_MAC_FORMAT,
        CTC_CLI_MAC_FORMAT,
        "Ip-sa",
        CTC_CLI_IPV4_FORMAT,
        CTC_CLI_IPV4_MASK_FORMAT,
        "Ip-da",
        CTC_CLI_IPV4_FORMAT,
        CTC_CLI_IPV4_MASK_FORMAT,
        "Cvlan-id",
        CTC_CLI_VLAN_RANGE_DESC,
        CTC_CLI_VLAN_RANGE_MASK,
        "Ctag-cos",
        CTC_CLI_COS_RANGE_DESC,
        CTC_CLI_COS_RANGE_MASK,
        "Svlan-id",
        CTC_CLI_VLAN_RANGE_DESC,
        CTC_CLI_VLAN_RANGE_MASK,
        "Stag-cos",
        CTC_CLI_COS_RANGE_DESC,
        CTC_CLI_COS_RANGE_MASK,
        "L3-type",
        "L3_TYPE ",
        "MASK",
        "Ctag-cfi",
        CTC_CLI_CFI_RANGE_DESC,
        "Stag-cfi",
        CTC_CLI_CFI_RANGE_DESC,
        "Stag-valid",
        "STAG_VALID",
        "Ctag-valid",
        "CTAG_VALID",
        "Vlan-num",
        "VLAN_MUM",
        "MASK",
        "L4-src-port",
        "L4_SRC_PORT",
        "MASK",
        "L4-dst-port",
        "L4_DST_PORT",
        "MASK",
        "IPv6 source address",
        CTC_CLI_IPV6_FORMAT,
        CTC_CLI_IPV6_MASK_FORMAT,
        "IPv6 destination address",
        CTC_CLI_IPV6_FORMAT,
        CTC_CLI_IPV6_MASK_FORMAT,
        "Fid",
        CTC_CLI_FID_DESC,
        "Volt-tag",
        "Volt-tag Value",
        "Vn-tag",
        "Vn-tag Value",
        "Xlate-nhid",
        CTC_CLI_NH_ID_STR,
        CTC_CLI_NH_DSNH_OFFSET_STR,
        CTC_CLI_NH_DSNH_OFFSET_VALUE_STR,
        "Logic_port",
        "Logic_port Value",
        "Igs-policer-id",
        "Ingress-policer-id",
        "Ingress vlan action",
        CTC_CLI_PON_VLAN_ACTION_DSCP,
        "Egress vlan action",
        CTC_CLI_PON_VLAN_ACTION_DSCP,
        "Pass-through-en")
{
     int32 ret = 0;
	 
     uint8 index = 0;
     uint8 start_index = 0;
     uint8 is_create = 0;
     uint8 is_update = 0;

    ipv6_addr_t ipv6_sa;
    ipv6_addr_t ipv6_sa_mask;
    ipv6_addr_t ipv6_da;
    ipv6_addr_t ipv6_da_mask;
    mac_addr_t  mac_sa;
    mac_addr_t  mac_da;
    mac_addr_t macsa_mask;
    mac_addr_t macda_mask;
    ctc_field_port_t port_info;
    ctc_field_port_t port_info_mask;
    ctc_acl_udf_t udf_data;
    ctc_acl_udf_t udf_mask;
    ctc_pon_vlan_port_t  vlan_port;
    ctc_field_key_t match_fields[20] ;
    uint16* field_num = &vlan_port.fields_num;
    ctc_field_key_t* p_field = match_fields;
    uint32 vlan_mapping_group = 0;
	ctc_xdata_t xdata;
	ctc_xdata_field_t xdata_field[35];
    *field_num = 0;

    sal_memset(&vlan_port, 0, sizeof(vlan_port));
    sal_memset(&match_fields, 0, sizeof(ctc_field_key_t)*20);
    sal_memset(&port_info, 0, sizeof(ctc_field_port_t));
    sal_memset(&port_info_mask, 0, sizeof(ctc_field_port_t));
    sal_memset(&udf_data, 0, sizeof(ctc_acl_udf_t));
    sal_memset(&udf_mask, 0, sizeof(ctc_acl_udf_t));
	sal_memset(&xdata, 0, sizeof(ctc_xdata_t));
	sal_memset(xdata_field, 0, sizeof(ctc_xdata_field_t)*35);

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("create");
    if (index != 0xFF)
    {
        is_create = 1;
    }
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("update");
    if (index != 0xFF)
    {
        is_update = 1;
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("uni");
    if (index != 0xFF)
    {
        vlan_port.flag = CTC_PON_VLAN_PORT_FLAG_FROM_UNI;  
    }
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("nni");
    if (index != 0xFF)
    {
        vlan_port.flag = CTC_PON_VLAN_PORT_FLAG_FROM_NNI;
    }
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("is-default");
    if (index != 0xFF) 
    {
        vlan_port.flag = CTC_PON_VLAN_PORT_FLAG_DEFAULT_SERVICE;
    }
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("scl-id");
    if (index != 0xFF) 
    {
        CTC_SET_FLAG(vlan_port.flag, CTC_PON_VLAN_PORT_FLAG_SCL_ID);
        CTC_CLI_GET_UINT8("scl-id", vlan_port.scl_id, argv[index + 1]);
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("vlan-port-id");
    if (index != 0xFF) 
    {
        CTC_CLI_GET_UINT32("vlan-port-id", vlan_port.vlan_port_id, argv[index + 1]);
    }
 
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("port");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("port", vlan_port.gport, argv[index + 1]);
    }
    
    CTC_SET_FLAG(vlan_port.flag, CTC_PON_VLAN_PORT_FLAG_PON_SERVICE);
    index= CTC_CLI_GET_ARGC_INDEX_ENHANCE("match-tunnel-value");
    if (index != 0xFF)
    {
        CTC_UNSET_FLAG(vlan_port.flag, CTC_PON_VLAN_PORT_FLAG_PON_SERVICE);
        CTC_CLI_GET_UINT32("tunnel value", vlan_port.tunnel_value, argv[index + 1]);
    }
     
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("logic-port");
    if (index != 0xFF)
    {
         CTC_CLI_GET_UINT32("logic-port", vlan_port.logic_port, argv[index + 1]);
    }
    vlan_port.criteria = CTC_PON_VLAN_PORT_MATCH_SVLAN;
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("match-svlan");
    if (index != 0xFF)
    {   
        CTC_CLI_GET_UINT16("match-svlan", match_fields[vlan_port.fields_num].data, argv[index + 1]);
        match_fields[vlan_port.fields_num].type = CTC_FIELD_KEY_SVLAN_ID; 
        index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("match-svlan-end");
        if (index != 0xFF)
        {   
            CTC_CLI_GET_UINT16("match-svlan-end", match_fields[vlan_port.fields_num].mask, argv[index + 1]);
            match_fields[vlan_port.fields_num].type = CTC_FIELD_KEY_SVLAN_RANGE;
        }
        vlan_port.fields_num ++;
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("match-cvlan");
    if (index != 0xFF)
    {
         vlan_port.criteria = CTC_PON_VLAN_PORT_MATCH_SVLAN_CVLAN;
         CTC_CLI_GET_UINT16("match-cvlan", match_fields[vlan_port.fields_num].data, argv[index + 1]);
         match_fields[vlan_port.fields_num].type = CTC_FIELD_KEY_CVLAN_ID;
         index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("match-cvlan-end");
        if (index != 0xFF)
        {   
            CTC_CLI_GET_UINT16("match-cvlan-end", match_fields[vlan_port.fields_num].mask, argv[index + 1]);
            match_fields[vlan_port.fields_num].type = CTC_FIELD_KEY_CVLAN_RANGE;
        }
         vlan_port.fields_num ++;
    }
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("match-scos");
    if (index != 0xFF)
    {
         CTC_CLI_GET_UINT16("match-scos", match_fields[vlan_port.fields_num].data, argv[index + 1]);
         match_fields[vlan_port.fields_num].type = CTC_FIELD_KEY_STAG_COS;
         vlan_port.fields_num ++;
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("match-ccos");
    if (index != 0xFF)
    {
         CTC_CLI_GET_UINT16("match-ccos", match_fields[vlan_port.fields_num].data, argv[index + 1]);
         match_fields[vlan_port.fields_num].type = CTC_FIELD_KEY_CTAG_COS;
         vlan_port.fields_num ++;
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("flex");
    if (0xFF != index) 
    {
        CTC_CLI_PON_FLEX_KEY_FIELD_TYPE_SET(p_field, CTC_CLI_ACL_KEY_ARG_CHECK(vlan_port.fields_num, 20, p_field));
        if (0xFF != CTC_CLI_GET_ARGC_INDEX_ENHANCE("use-mac-key"))
        {
            vlan_port.criteria = CTC_PON_VLAN_PORT_MATCH_FLEX_MAC;
        }
        else if (0xFF != CTC_CLI_GET_ARGC_INDEX_ENHANCE("use-ipv6-key"))
        {
            vlan_port.criteria = CTC_PON_VLAN_PORT_MATCH_FLEX_IPV6;
        }
        else
        {
            vlan_port.criteria = CTC_PON_VLAN_PORT_MATCH_FLEX_IPV4;
        }
    }

    vlan_port.match_fields = &match_fields[0];
    
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("fid");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT16("fid", vlan_port.fid, argv[index + 1]);
        if(is_update)
        {
            CTC_SET_FLAG(vlan_port.flag, CTC_PON_VLAN_PORT_FLAG_FID);
        }
    }
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("volt-tag");
    if (index != 0xFF)
    {
        vlan_port.volt_tag_valid = 1;
        CTC_CLI_GET_UINT16("volt-tag", vlan_port.volt_tag, argv[index + 1]);
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("vn-tag");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT16("volt-tag", vlan_port.vn_tag, argv[index + 1]);
        CTC_SET_FLAG(vlan_port.flag, CTC_PON_VLAN_PORT_FLAG_VN_TAG);
    }
    
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("xlate-nhid");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("xlate-nhid", vlan_port.xlate_nhid, argv[index + 1]);
    }
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("dsnh-offset");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("dsnh-offset", vlan_port.dsnh_offset, argv[index + 1]);
    }
    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("logic_port");
    if (index != 0xFF)
    {
        CTC_CLI_GET_UINT32("xlate-nhid", vlan_port.logic_port, argv[index + 1]);
    }

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("igs-policer-id");
    if (index != 0xFF)
    {
        CTC_SET_FLAG(vlan_port.flag, CTC_PON_VLAN_PORT_FLAG_IGS_POLICER);
        CTC_CLI_GET_UINT32("igs-policer-id", vlan_port.igs_policer_id, argv[index + 1]);
    }  

    index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("pass-through-en");
    if (index != 0xFF)
    {
        CTC_SET_FLAG(vlan_port.flag, CTC_PON_VLAN_PORT_FLAG_PASS_THROUGH);
    }    

    /*igress action*/
	 
    start_index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("igs-vlan-action");

    if (start_index != 0xFF)
    {
        ret = _ctc_app_cli_parser_vlan_action2(vty, argc,
                                        &argv[0],
                                        start_index,
                                        "svlan",
                                       (uint8 *) &vlan_port.igs_vlan_action.stag_op,
                                       (uint8 *) &vlan_port.igs_vlan_action.svid_sl,
                                       (uint16 *) &vlan_port.igs_vlan_action.svid_new);

        ret = ret ? ret : _ctc_app_cli_parser_vlan_action2(vty, argc,
                                        &argv[0],
                                        start_index,
                                        "cvlan",
                                        (uint8 *)&vlan_port.igs_vlan_action.ctag_op,
                                        (uint8 *)&vlan_port.igs_vlan_action.cvid_sl,
                                        (uint16 *)&vlan_port.igs_vlan_action.cvid_new);

    }

     /*egress action*/

    start_index = CTC_CLI_GET_ARGC_INDEX_ENHANCE("egs-vlan-action");

    if (start_index != 0xFF)
    {
        ret = _ctc_app_cli_parser_vlan_action2(vty, argc,
                                        &argv[0],
                                        start_index,
                                        "svlan",
                                        (uint8 *)&vlan_port.egs_vlan_action.stag_op,
                                        (uint8 *)&vlan_port.egs_vlan_action.svid_sl,
                                        (uint16 *)&vlan_port.egs_vlan_action.svid_new);

        ret = ret ? ret : _ctc_app_cli_parser_vlan_action2(vty, argc,
                                        &argv[0],
                                        start_index,
                                        "cvlan",
                                        (uint8 *)&vlan_port.egs_vlan_action.ctag_op,
                                        (uint8 *)&vlan_port.egs_vlan_action.cvid_sl,
                                        (uint16 *)&vlan_port.egs_vlan_action.cvid_new);

    }

    if(g_ctcs_api_en)
    {
         if (is_create)
         {
            ret = ctcs_pon_create_vlan_port(g_api_ldev, &vlan_port);           
         }
         else if(is_update)
         {
            ret = ctcs_pon_update_vlan_port(g_api_ldev, &vlan_port);  
         }
         else
         {
            ret = ctcs_pon_destroy_vlan_port(g_api_ldev, &vlan_port);
         }
    }
    else
    {
         if (is_create)
         {
             ret = ctc_pon_create_vlan_port(&vlan_port);           
         }
         else if(is_update)
         {
             ret = ctc_pon_update_vlan_port(&vlan_port); 
         }
         else
         {
            ret = ctc_pon_destroy_vlan_port(&vlan_port);
         }
    }

   if (ret < 0)
   {
        ctc_cli_out("%% %s\n", ctc_get_error_desc(ret));
        return CLI_ERROR;
   }
   if (is_create || is_update)
    {
       ctc_cli_out("%-20s%-15d\n","vlan port id: ",   vlan_port.vlan_port_id);
       ctc_cli_out("%-20s%-15d\n","logic port : ",   vlan_port.logic_port);
       ctc_cli_out("%-20s%-15d\n","fid: ",   vlan_port.fid);
       ctc_cli_out("%-20s%-15d\n","match-tunnel-value: ",   vlan_port.tunnel_value);
       ctc_cli_out("%-20s0X%-13x\n","scl-entry-id: ",   vlan_port.scl_eid);
    }
   
   return ret;

}


CTC_CLI(ctc_cli_pon_get_vlan_port,
        ctc_cli_pon_get_vlan_port_cmd,
        "show pon vlan-port vlan-port-id ID",
        "Show",
        "Pon",
        "Vlan-port",
        "Vlan-port-id",
        "ID")
{
    int32 ret = 0;
    ctc_pon_vlan_port_t cfg;

    sal_memset(&cfg, 0, sizeof(cfg));

    CTC_CLI_GET_UINT32("vlan-port-id", cfg.vlan_port_id, argv[0]);
 
    if(g_ctcs_api_en)
    {
        ret = ctcs_pon_get_vlan_port(g_api_ldev,&cfg);
    }
    else
    {
        ret = ctc_pon_get_vlan_port(&cfg);
    }

    if (ret < 0)
    {
        ctc_cli_out("%% %s\n", ctc_get_error_desc(ret));
        return CLI_ERROR;
    }
   else
    {
        ctc_cli_out("---------------------------------------------------------------\n");
        ctc_cli_out("%-15s%-10d\n","gport:" , cfg.gport);
        ctc_cli_out("%-15s%-10d\n","vlan-port-id:" , cfg.vlan_port_id);
        ctc_cli_out("%-15s%-10d\n","criteria:" , cfg.criteria);
        ctc_cli_out("%-15s%-10d\n","tunnel-value:" , cfg.tunnel_value);
        ctc_cli_out("%-15s%-10d\n","fid:" , cfg.fid);
        ctc_cli_out("%-15s%-10d\n","xlate-nhid:" , cfg.xlate_nhid);
        ctc_cli_out("%-15s%-10d\n","logic-port:" , cfg.logic_port);
        ctc_cli_out("%-15s%-10d\n","igs-policer-id:" , cfg.igs_policer_id);
        ctc_cli_out("%-15s0X%-8x\n","scl-entry-id:" , cfg.scl_eid);
        ctc_cli_out("%-15s%-10d\n","scl id:" , cfg.scl_id);
        ctc_cli_out("---------------------------------------------------------------\n");
    }   
    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_pon_debug_on,
        ctc_cli_pon_debug_on_cmd,
        "debug pon (ctc|sys) (debug-level {func|param|info|error} |)",
        CTC_CLI_DEBUG_STR,
        "PON module",
        "CTC layer",
        "Sys layer",
        CTC_CLI_DEBUG_LEVEL_STR,
        CTC_CLI_DEBUG_LEVEL_FUNC,
        CTC_CLI_DEBUG_LEVEL_PARAM,
        CTC_CLI_DEBUG_LEVEL_INFO,
        CTC_CLI_DEBUG_LEVEL_ERROR)
{
    uint32 typeenum = 0;
    uint8 level = CTC_DEBUG_LEVEL_INFO;
    uint8 index = 0;

    index = CTC_CLI_GET_ARGC_INDEX("debug-level");
    if (index != 0xFF)
    {
        level = CTC_DEBUG_LEVEL_NONE;
        index = CTC_CLI_GET_ARGC_INDEX("func");
        if (index != 0xFF)
        {
            level |= CTC_DEBUG_LEVEL_FUNC;
        }

        index = CTC_CLI_GET_ARGC_INDEX("param");
        if (index != 0xFF)
        {
            level |= CTC_DEBUG_LEVEL_PARAM;
        }

        index = CTC_CLI_GET_ARGC_INDEX("info");
        if (index != 0xFF)
        {
            level |= CTC_DEBUG_LEVEL_INFO;
        }

        index = CTC_CLI_GET_ARGC_INDEX("error");
        if (index != 0xFF)
        {
            level |= CTC_DEBUG_LEVEL_ERROR;
        }
    }

    if (0 == sal_memcmp(argv[0], "ctc", 3))
    {
        typeenum = PON_CTC;
    }
    else
    {
        typeenum = PON_SYS;
    }

    ctc_debug_set_flag("pon", "pon", typeenum, level, TRUE);

    return CLI_SUCCESS;
}

CTC_CLI(ctc_cli_pon_debug_off,
        ctc_cli_pon_debug_off_cmd,
        "no debug pon (ctc|sys)",
        CTC_CLI_NO_STR,
        CTC_CLI_DEBUG_STR,
        "PON module",
        "CTC layer",
        "Sys layer")
{
    uint32 typeenum = 0;
    uint8 level = CTC_DEBUG_LEVEL_INFO;

    if (0 == sal_memcmp(argv[0], "ctc", 3))
    {
        typeenum = FTM_CTC;
    }
    else
    {
        typeenum = FTM_SYS;
    }

    ctc_debug_set_flag("pon", "pon", typeenum, level, FALSE);

    return CLI_SUCCESS;
}


int32
ctc_pon_cli_init(void)
{    
    install_element(CTC_SDK_MODE, &ctc_cli_pon_module_init_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_pon_set_port_properity_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_pon_get_port_properity_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_pon_create_gem_port_cmd);

    install_element(CTC_SDK_MODE, &ctc_cli_pon_create_vlan_port_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_pon_get_vlan_port_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_pon_module_deinit_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_pon_debug_on_cmd);
    install_element(CTC_SDK_MODE, &ctc_cli_pon_debug_off_cmd);
     
    return CLI_SUCCESS;
}
#endif

